﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;

namespace Scrabble.Model
{
    [ContractClass(typeof(CodeContractForIPlayer))]
    public interface IPlayer
    {
        string Name { get; }

        bool IsActive { get; }

        int CurrentScore { get; }
        IEnumerable<Tile> CurrentTiles { get; }

        TimeSpan TimeInGame { get; }

        void Pass();
        void PlaceTiles(IEnumerable<Tile> tiles, PlayVector vector);
        void ExchangeTiles(Tile[] tiles);

        // What about rejecting plays? forfeit
    }

    [ContractClassFor(typeof(IPlayer))]
    abstract class CodeContractForIPlayer : IPlayer
    {
        public void ExchangeTiles(Tile[] tiles)
        {
            Contract.Requires<ArgumentNullException>(tiles != null);
            Contract.Requires<ArgumentException>(tiles.Length > 0);
        }
    
        public void PlaceTiles(IEnumerable<Tile> tiles, PlayVector vector)
        {
            Contract.Requires<ArgumentNullException>(tiles != null);
            Contract.Requires<ArgumentException>(tiles.Any());

            Contract.Requires<ArgumentNullException>(vector != null);
            Contract.Requires<ArgumentOutOfRangeException>(vector.StartingLocation.IsWithinBounds, "Error: invalid start location");
        }
    
        public void Pass()
        {

        }

        public string Name
        {
            get
            {
                Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));
                throw new NotImplementedException();
            }
        }

        public bool IsActive
        {
            get { throw new NotImplementedException(); }
        }

        public int CurrentScore
        {
            get { throw new NotImplementedException(); }
        }

        public IEnumerable<Tile> CurrentTiles
        {
            get { throw new NotImplementedException(); }
        }

        public TimeSpan TimeInGame
        {
            get { throw new NotImplementedException(); }
        }
    }
}